<template>
  <div class="Intersection-observer">
    <div class="window-view" ref="windowView">
      <div class="window-view-content">
        <div class="window-view-item" ref="viewItem"></div>
      </div>
    </div>
    <div class="title">可视宽度：{{currentWidth}}</div>
    <div class="title">可视高度：{{currentHeight}}</div>
    <div class="title">可视面积：{{area}}</div>
    <div class="title">可视比例：{{intersectionRatio}}</div>
    <a href="https://caniuse.com/#search=IntersectionObserver" target="_blank">查看兼容性</a>
    <pre v-highlightjs class="code-pre">
      <code class="javascript">
      /**
       *检测一个元素是否可见
       *IntersectionObserver 能让你知道一个被观测的元素什么时候进入或离开浏览器的可见窗口。
       * @type {IntersectionObserver}
       */
      this.io = new IntersectionObserver(entries => {
        this.currentWidth = entries[0].intersectionRect.width;
        this.currentHeight = entries[0].intersectionRect.height;
        this.intersectionRatio = entries[0].intersectionRatio;
      }, {
        // 用于计算相交区域的根元素
        // 如果未提供，使用最上级文档的可见窗口
        root: this.$refs.windowView,
        // 同 margin，可以是 1、2、3、4 个值，允许时负值。
        // 如果显式指定了跟元素，该值可以使用百分比，即根元素大小的百分之多少。
        // 如果没指定根元素，使用百分比会出错。
        rootMargin: "0px",
        // 触发回调函数的临界值，用 0 ~ 1 的比率指定，也可以是一个数组。
        // 其值是被观测元素可视面积 / 总面积。
        // 当可视比率经过这个值的时候，回调函数就会被调用。
        threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
      });
      this.io.observe(this.$refs.viewItem)
      </code>
    </pre>
  </div>
</template>

<script>
  export default {
    name: "IntersectionObserver",
    data() {
      return {
        io: '',
        currentWidth: 0,
        currentHeight: 0,
        intersectionRatio: 0
      }
    },
    computed: {
      area() {
        return this.currentWidth * this.currentHeight
      }
    },
    mounted() {
      /**
       *检测一个元素是否可见
       *IntersectionObserver 能让你知道一个被观测的元素什么时候进入或离开浏览器的可见窗口。
       * @type {IntersectionObserver}
       */
      this.io = new IntersectionObserver(entries => {
        this.currentWidth = entries[0].intersectionRect.width;
        this.currentHeight = entries[0].intersectionRect.height;
        this.intersectionRatio = entries[0].intersectionRatio;
        this.test();
      }, {
        // 用于计算相交区域的根元素
        // 如果未提供，使用最上级文档的可见窗口
        /*root: this.$refs.windowView,*/
        // 同 margin，可以是 1、2、3、4 个值，允许时负值。
        // 如果显式指定了跟元素，该值可以使用百分比，即根元素大小的百分之多少。
        // 如果没指定根元素，使用百分比会出错。
        rootMargin: "0px",
        // 触发回调函数的临界值，用 0 ~ 1 的比率指定，也可以是一个数组。
        // 其值是被观测元素可视面积 / 总面积。
        // 当可视比率经过这个值的时候，回调函数就会被调用。
        threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
        //threshold: [0.1],
      });
      this.io.observe(this.$refs.viewItem)
    },
    methods: {
      test() {
        console.log('我只执行一次');
        this.test = () => {};
      }
    },
    beforeDestroy() {
      this.io.unobserve(this.$refs.viewItem);
    }
  }
</script>

<style scoped>
  .title {
    font-weight: 700;
    margin-top: 10px;
    margin-bottom: 10px;
  }

  .window-view {
    width: 400px;
    height: 400px;
    border: 1px solid #ccc;
    overflow: auto;
  }

  .window-view-content {
    width: 800px;
    height: 800px;
  }

  .window-view-item {
    width: 200px;
    height: 200px;
    background-color: dodgerblue;
  }
</style>
